/*
 * @文件描述: TFT驱动程序，ILI9806G
 * @版本: 
 * @作者: 周晨阳
 * @Date: 2021-01-14 08:26:53
 */

#include "TFT.h"
#include <stdio.h>
#include "GUI.h"
#include <rtthread.h>
#include "SDL.h"
#include <stdbool.h>
#include <rtthread.h>
#ifndef MONITOR_ZOOM
#define MONITOR_ZOOM 1
#endif
//根据液晶扫描方向而变化的XY像素宽度
//调用TFT_GramScan函数设置方向时会自动更改
uint16_t LCD_X_LENGTH = TFT_MORE_PIXEL;
uint16_t LCD_Y_LENGTH = TFT_LESS_PIXEL;

#ifndef MONITOR_HOR_RES
#define MONITOR_HOR_RES TFT_MORE_PIXEL
#endif

#ifndef MONITOR_VER_RES
#define MONITOR_VER_RES TFT_LESS_PIXEL
#endif
//液晶屏扫描模式，本变量主要用于方便选择触摸屏的计算参数
//参数可选值为0-7
//调用TFT_GramScan函数设置方向时会自动更改
//LCD刚初始化完成时会使用本默认值
uint8_t LCD_SCAN_MODE = 6;

static uint16_t CurrentTextColor = WHITE; //前景色
static uint16_t CurrentBackColor = BLUE;  //背景色

static int touchX, touchY;
typedef struct
{
  SDL_Window *window;
  SDL_Renderer *renderer;
  SDL_Texture *texture;
  SDL_Surface *surface;
  volatile bool sdl_refr_qry;
  uint16_t tft_fb[TFT_MORE_PIXEL * TFT_LESS_PIXEL];
} monitor_t;
monitor_t monitor;
static volatile bool sdl_inited = false;
static volatile bool sdl_quit_qry = false;

__inline static void WriteData(u16 tem_data);
__inline static void WriteComm(u16 CMD);
__inline uint16_t TFT_Read_Data(void);
static uint16_t TFT_Read_PixelData(void);
static void LCD_REG_Config(void);
static void LCD_WR_REG(u16 Index, u16 CongfigTemp);

static void TFT_SetCursor(uint16_t usX, uint16_t usY);
static void LCD_Rst(void);
static __inline void TFT_FillColor(uint32_t ulAmout_Point, uint16_t usColor);

static void window_create(monitor_t *m);
static void window_update(monitor_t *m);
int quit_filter(void *userdata, SDL_Event *event);
static void monitor_sdl_clean_up(void);
static void monitor_sdl_init(void);
static void sdl_event_handler();
static void monitor_sdl_refr();

static struct rt_thread SDL_ptr;
static rt_uint8_t SDL_stack[TFT_MORE_PIXEL * TFT_LESS_PIXEL*20];

static int quit_filter(void *userdata, SDL_Event *event)
{
  (void)userdata;

  if (event->type == SDL_WINDOWEVENT)
  {
    if (event->window.event == SDL_WINDOWEVENT_CLOSE)
    {
      sdl_quit_qry = true;
    }
  }
  else if (event->type == SDL_QUIT)
  {
    sdl_quit_qry = true;
  }

  return 1;
}

/**
 * @description: 写数据函数
 * @param {*}
 * @return {*}
 */
static void WriteData(u16 tem_data)
{
  // *(__IO uint16_t *)(FSMC_Addr_TFT_DATA) = tem_data;
}
/**
 * @description: 写命令函数
 * @param {*}
 * @return {*}
 */
static void WriteComm(u16 CMD)
{
  // *(__IO uint16_t *)(FSMC_Addr_TFT_CMD) = CMD;
}
/**
 * @description: 简易延时
 * @param {*}
 * @return {*}
 */
static void Delay(__IO u32 nCount)
{
  int i;
  for (i = 0; i < 0X7200; i++)
    for (; nCount != 0; nCount--)
      ;
}
/**
 * @brief  在TFT显示器上以某一颜色填充像素点
 * @param  ulAmout_Point ：要填充颜色的像素点的总数目
 * @param  usColor ：颜色
 * @retval 无
 */
static void TFT_FillColor(uint32_t ulAmout_Point, uint16_t usColor)
{
  uint32_t i = 0;
  //原版
  /* memory write */
  WriteComm(CMD_SetPixel);

  for (i = 0; i < ulAmout_Point; i++)
    WriteData(usColor);

  //优化版
  // *(__IO uint16_t *)(FSMC_Addr_TFT_CMD) =
  //     (CMD_SetPixel);

  // for (i = 0; i < ulAmout_Point; i++)
  //   *(__IO uint16_t *)(FSMC_Addr_TFT_DATA) = (usColor);
}

void LCD_FSMC_Init(void)
{
}
/*
 * 函数名：LCD_GPIO_Config
 * 描述  ：根据FSMC配置LCD的I/O
 * 输入  ：无
 * 输出  ：无
 * 调用  ：内部调用
 * 如果外部SRAM在TFT之前被初始化，则注释掉的引脚即为已经被初始化过了的
 */
void LCD_GPIO_Config(void)
{
}

/**
 * @brief  在TFT显示器上开辟一个窗口
 * @param  usX ：在特定扫描方向下窗口的起点X坐标
 * @param  usY ：在特定扫描方向下窗口的起点Y坐标
 * @param  usWidth ：窗口的宽度
 * @param  usHeight ：窗口的高度
 * @retval 无
 */
void TFT_OpenWindow(uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight)
{
  //原版：
  WriteComm(CMD_SetCoordinateX); /* 设置X坐标 */
  WriteData(usX >> 8);           /* 先高8位，然后低8位 */
  WriteData(usX & 0xff);         /* 设置起始点和结束点*/
  WriteData((usX + usWidth - 1) >> 8);
  WriteData((usX + usWidth - 1) & 0xff);

  WriteComm(CMD_SetCoordinateY); /* 设置Y坐标*/
  WriteData(usY >> 8);
  WriteData(usY & 0xff);
  WriteData((usY + usHeight - 1) >> 8);
  WriteData((usY + usHeight - 1) & 0xff);

  //优化版：
  // *(__IO uint16_t *)(FSMC_Addr_TFT_CMD) = (CMD_SetCoordinateX); /* 设置X坐标 */
  // *(__IO uint16_t *)(FSMC_Addr_TFT_DATA) = (usX >> 8);          /* 先高8位，然后低8位 */
  // *(__IO uint16_t *)(FSMC_Addr_TFT_DATA) = (usX & 0xff);        /* 设置起始点和结束点*/
  // *(__IO uint16_t *)(FSMC_Addr_TFT_DATA) = ((usX + usWidth - 1) >> 8);
  // *(__IO uint16_t *)(FSMC_Addr_TFT_DATA) = ((usX + usWidth - 1) & 0xff);

  // *(__IO uint16_t *)(FSMC_Addr_TFT_CMD) = (CMD_SetCoordinateY); /* 设置Y坐标*/
  // *(__IO uint16_t *)(FSMC_Addr_TFT_DATA) = (usY >> 8);
  // *(__IO uint16_t *)(FSMC_Addr_TFT_DATA) = (usY & 0xff);
  // *(__IO uint16_t *)(FSMC_Addr_TFT_DATA) = ((usY + usHeight - 1) >> 8);
  // *(__IO uint16_t *)(FSMC_Addr_TFT_DATA) = ((usY + usHeight - 1) & 0xff);
}

/**
 * @brief  设定TFT的光标坐标
 * @param  usX ：在特定扫描方向下光标的X坐标
 * @param  usY ：在特定扫描方向下光标的Y坐标
 * @retval 无
 */
static void TFT_SetCursor(uint16_t usX, uint16_t usY)
{

  TFT_OpenWindow(usX, usY, 1, 1);
}

/**
 * @description: tft屏幕硬件初始化，内部使用
 * @param {*}
 * @return {*}
 */
static void LCD_Rst(void)
{
  // GPIO_ResetBits(TFT_RST_PORT, TFT_RST_PIN); //µÍµçÆ½¸´Î»

  Delay(6000);

  // GPIO_SetBits(TFT_RST_PORT, TFT_RST_PIN);

  Delay(6000);
}

/**
  * @brief  从TFT读取数据
  * @param  无
  * @retval 读取到的数据
  */
__inline uint16_t TFT_Read_Data(void)
{
  // return (*(__IO uint16_t *)(FSMC_Addr_TFT_DATA));
}
/**
 * @brief  读取TFT GRAN 的一个像素数据
 * @param  无
 * @retval 像素数据
 */
static uint16_t TFT_Read_PixelData(void)
{
  uint16_t usR = 0, usG = 0, usB = 0;

  WriteComm(0x2E); /* 读数据 */
  //原版：
  usR = TFT_Read_Data(); /*FIRST READ OUT DUMMY DATA*/

  usR = TFT_Read_Data(); /*READ OUT RED DATA  */
  usB = TFT_Read_Data(); /*READ OUT BLUE DATA*/
  usG = TFT_Read_Data(); /*READ OUT GREEN DATA*/

  //优化版
  // usR = (*(__IO uint16_t *)(FSMC_Addr_TFT_DATA)); /*FIRST READ OUT DUMMY DATA*/

  // usR = (*(__IO uint16_t *)(FSMC_Addr_TFT_DATA)); /*READ OUT RED DATA  */
  // usB = (*(__IO uint16_t *)(FSMC_Addr_TFT_DATA)); /*READ OUT BLUE DATA*/
  // usG = (*(__IO uint16_t *)(FSMC_Addr_TFT_DATA)); /*READ OUT GREEN DATA*/

  return (((usR >> 11) << 11) | ((usG >> 10) << 5) | (usB >> 11));
}
void TFT_SetPixel(uint16_t usX, uint16_t usY, uint16_t color)
{
  monitor.tft_fb[usX + usY * MONITOR_HOR_RES] = color;

  //monitor.sdl_refr_qry = true;
}
/**
 * @brief  对TFT显示器的某一点以某种颜色进行填充
 * @param  usX ：在特定扫描方向下该点的X坐标
 * @param  usY ：在特定扫描方向下该点的Y坐标
 * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
 * @retval 无
 */
void TFT_SetPointPixel(uint16_t usX, uint16_t usY)
{
  //if ((usX < LCD_X_LENGTH) && (usY < LCD_Y_LENGTH))
  {
    //memset(monitor.tft_fb, i += 0x12, MONITOR_HOR_RES * MONITOR_VER_RES * sizeof(uint16_t));
    monitor.tft_fb[usX + usY * MONITOR_HOR_RES] = CurrentTextColor;

    monitor.sdl_refr_qry = true;

    //monitor_sdl_refr();
  }
}
/**
 * @brief  获取 TFT 显示器上某一个坐标点的像素数据
 * @param  usX ：在特定扫描方向下该点的X坐标
 * @param  usY ：在特定扫描方向下该点的Y坐标
 * @retval 像素数据
 */
uint16_t TFT_GetPointPixel(uint16_t usX, uint16_t usY)
{

  return monitor.tft_fb[usX + usY * MONITOR_HOR_RES];
}
void SDL_Draw_H_Line(int x0, int y, int x1, uint16_t color)
{

  memset(&monitor.tft_fb[x0 + (y )* MONITOR_HOR_RES], color, (abs(x1 - x0)) * sizeof(uint16_t));
}
/**
 * @brief  在 TFT 显示器上使用 Bresenham 算法画线段 
 * @param  usX1 ：在特定扫描方向下线段的一个端点X坐标
 * @param  usY1 ：在特定扫描方向下线段的一个端点Y坐标
 * @param  usX2 ：在特定扫描方向下线段的另一个端点X坐标
 * @param  usY2 ：在特定扫描方向下线段的另一个端点Y坐标
 * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
 * @retval 无
 */
void TFT_DrawLine(uint16_t usX1, uint16_t usY1, uint16_t usX2, uint16_t usY2)
{
  uint16_t us;
  uint16_t usX_Current, usY_Current;

  int32_t lError_X = 0, lError_Y = 0, lDelta_X, lDelta_Y, lDistance;
  int32_t lIncrease_X, lIncrease_Y;

  lDelta_X = usX2 - usX1; //计算坐标增量
  lDelta_Y = usY2 - usY1;

  usX_Current = usX1;
  usY_Current = usY1;

  if (lDelta_X > 0)
    lIncrease_X = 1; //设置单步方向

  else if (lDelta_X == 0)
    lIncrease_X = 0; //垂直线

  else
  {
    lIncrease_X = -1;
    lDelta_X = -lDelta_X;
  }

  if (lDelta_Y > 0)
    lIncrease_Y = 1;

  else if (lDelta_Y == 0)
    lIncrease_Y = 0; //水平线

  else
  {
    lIncrease_Y = -1;
    lDelta_Y = -lDelta_Y;
  }

  if (lDelta_X > lDelta_Y)
    lDistance = lDelta_X; //选取基本增量坐标轴

  else
    lDistance = lDelta_Y;

  for (us = 0; us <= lDistance + 1; us++) //画线输出
  {
    TFT_SetPointPixel(usX_Current, usY_Current); //画点

    lError_X += lDelta_X;
    lError_Y += lDelta_Y;

    if (lError_X > lDistance)
    {
      lError_X -= lDistance;
      usX_Current += lIncrease_X;
    }

    if (lError_Y > lDistance)
    {
      lError_Y -= lDistance;
      usY_Current += lIncrease_Y;
    }
  }
}
/**
 * @brief  在 TFT 显示器上画一个矩形
 * @param  usX_Start ：在特定扫描方向下矩形的起始点X坐标
 * @param  usY_Start ：在特定扫描方向下矩形的起始点Y坐标
 * @param  usWidth：矩形的宽度（单位：像素）
 * @param  usHeight：矩形的高度（单位：像素）
 * @param  ucFilled ：选择是否填充该矩形
  *   该参数为以下值之一：
  *     @arg 0 :空心矩形
  *     @arg 1 :实心矩形 
 * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
 * @retval 无
 */
void TFT_DrawRectangle(uint16_t usX_Start, uint16_t usY_Start, uint16_t usWidth, uint16_t usHeight, uint8_t ucFilled)
{
  if (ucFilled)
  {
    TFT_OpenWindow(usX_Start, usY_Start, usWidth, usHeight);
    TFT_FillColor(usWidth * usHeight, CurrentTextColor);
  }
  else
  {
    TFT_DrawLine(usX_Start, usY_Start, usX_Start + usWidth - 1, usY_Start);
    TFT_DrawLine(usX_Start, usY_Start + usHeight - 1, usX_Start + usWidth - 1, usY_Start + usHeight - 1);
    TFT_DrawLine(usX_Start, usY_Start, usX_Start, usY_Start + usHeight - 1);
    TFT_DrawLine(usX_Start + usWidth - 1, usY_Start, usX_Start + usWidth - 1, usY_Start + usHeight - 1);
  }
}

/**
 * @brief  对TFT显示器的某一窗口以某种颜色进行清屏
 * @param  usX ：在特定扫描方向下窗口的起点X坐标
 * @param  usY ：在特定扫描方向下窗口的起点Y坐标
 * @param  usWidth ：窗口的宽度
 * @param  usHeight ：窗口的高度
 * @note 可使用LCD_SetBackColor、LCD_SetTextColor、LCD_SetColors函数设置颜色
 * @retval 无
 */
void TFT_Clear(uint16_t usX, uint16_t usY, uint16_t usWidth, uint16_t usHeight)
{
  TFT_OpenWindow(usX, usY, usWidth, usHeight);

  TFT_FillColor(usWidth * usHeight, CurrentBackColor);
}
void TFT_ClearFull(uint16_t color)
{
  CurrentBackColor = color;
  TFT_Clear(0, 0, 480, TFT_MORE_PIXEL);
}
void TFT_GramScan(uint8_t ucOption)
{
}

/**
 * @description: TFT初始化寄存器配置代码，内部使用
 * @param {*}
 * @return {*}
 */
static void LCD_REG_Config(void)
{
}
/**
 * @description:tft屏幕背光控制
 * @param {int} State ：1为开启，0为关闭
 * @return {*}
 */
void TFT_BackLed_Control(int State)
{
  if (!State)
  {
    // GPIO_ResetBits(TFT_BK_PORT, TFT_BK_PIN);
  }
  else
  {
    // GPIO_SetBits(TFT_BK_PORT, TFT_BK_PIN);
  }
}

/**
 * SDL main thread. All SDL related task have to be handled here!
 * It initializes SDL, handles drawing and the mouse.
 */
static int sdlFPS = 0;
int getSDL_FPS()
{
  return sdlFPS;
}
void clearSDL_FPS()
{
  sdlFPS = 0;
}
#ifdef GUI_UCGUI
static void sdl_event_handler()
{
  static int mouseState = 0;
  //rt_thread_mdelay(500);
  window_create(&monitor);
  //rt_thread_mdelay(500);
  static int i = 0;
  while (1)
  {
    sdlFPS++;

    rt_thread_mdelay(16);
    //  memset(monitor.tft_fb, i+=0x12, MONITOR_HOR_RES * MONITOR_VER_RES * sizeof(uint16_t));
    window_update(&monitor);

    /*Refresh handling*/
    SDL_Event event;

    while (SDL_PollEvent(&event))
    {
      //printf("into sdl event\n");
      if ((&event)->type == SDL_WINDOWEVENT)
      {
        printf("event:%d\n", (&event)->window.event);
        switch ((&event)->window.event)
        {
#if SDL_VERSION_ATLEAST(2, 0, 5)
        case SDL_WINDOWEVENT_TAKE_FOCUS:
          break;
#endif
        case SDL_WINDOWEVENT_SHOWN:
          //window_update(&monitor);
          break;
        case SDL_WINDOWEVENT_CLOSE:
          monitor_sdl_clean_up();
          exit(0);
          break;
        case SDL_WINDOWEVENT_EXPOSED:
          window_update(&monitor);

          break;
        default:
          //window_update(&monitor);
          break;
        }
      }
      else if ((&event)->type == SDL_MOUSEMOTION)
      {
        if (mouseState)
        {
          touchX = event.motion.x / MONITOR_ZOOM;
          touchY = event.motion.y / MONITOR_ZOOM;
        }
        //printf("x:%d,y:%d \n", (&event)->motion.x, (&event)->motion.y);
        // touchX = event.motion.x / MONITOR_ZOOM;
        // touchY = event.motion.y / MONITOR_ZOOM;
      }
      else if ((&event)->type == SDL_MOUSEBUTTONDOWN)
      {
        if (event.button.button = SDL_BUTTON_LEFT)
        {
          mouseState = 1;
          touchX = event.motion.x / MONITOR_ZOOM;
          touchY = event.motion.y / MONITOR_ZOOM;
          printf("x:%d,y:%d \n", touchX, touchY);
        }
        /* code */
      }
      else if ((&event)->type == SDL_MOUSEBUTTONUP)
      {
        if (event.button.button = SDL_BUTTON_LEFT)
        {
          mouseState = 0;
        }
        /* code */
      }

      else
      {
        touchX = 0xffff;
        touchY = 0xffff;
      }
    }

    /*Run until quit event not arrives*/
    if (sdl_quit_qry)
    {
      monitor_sdl_clean_up();
      exit(0);
    }
  }
}

#endif
static void monitor_sdl_refr()
{

  /*Refresh handling*/
  if (monitor.sdl_refr_qry != false)
  {
    monitor.sdl_refr_qry = false;
    window_update(&monitor);
  }
}
static void monitor_sdl_clean_up(void)
{
  SDL_DestroyTexture(monitor.texture);
  SDL_DestroyRenderer(monitor.renderer);
  SDL_DestroyWindow(monitor.window);

  SDL_Quit();
}
void SDL_Update()
{
  //window_update(&monitor);
}
static void window_update(monitor_t *m)
{
  SDL_UpdateTexture(m->texture, NULL, m->tft_fb, MONITOR_HOR_RES * sizeof(uint16_t));

  SDL_RenderClear(m->renderer);

  /*Update the renderer with the texture containing the rendered image*/
  SDL_RenderCopy(m->renderer, m->texture, NULL, NULL);
  SDL_RenderPresent(m->renderer);
}
#ifdef GUI_UCGUI

static void window_create(monitor_t *m)
{
  m->window = SDL_CreateWindow("TFT Simulator",
                               SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
                               MONITOR_HOR_RES * MONITOR_ZOOM, MONITOR_VER_RES * MONITOR_ZOOM, SDL_WINDOW_RESIZABLE); /*last param. SDL_WINDOW_BORDERLESS to hide borders*/

  m->renderer = SDL_CreateRenderer(m->window, -1, SDL_RENDERER_SOFTWARE);
  m->texture = SDL_CreateTexture(m->renderer,
                                 SDL_PIXELFORMAT_RGB565, SDL_TEXTUREACCESS_STREAMING, MONITOR_HOR_RES, MONITOR_VER_RES);
  m->surface = SDL_GetWindowSurface(m->window);
  SDL_SetTextureBlendMode(m->texture, SDL_BLENDMODE_BLEND);

  /*Initialize the frame buffer to gray (77 is an empirical value) */

  //memset(m->tft_fb, 0xaaaa, MONITOR_HOR_RES * MONITOR_VER_RES * sizeof(uint16_t)/4);

  m->sdl_refr_qry = true;
  monitor_sdl_refr();
}
#endif
/**********************************************
Lcd初始化函数，外部调用
***********************************************/
void Lcd_Initialize(void)
{
  #ifdef GUI_UCGUI
  SDL_Init(SDL_INIT_VIDEO);
  SDL_SetEventFilter(quit_filter, NULL);

  //sdl_inited = true;

  //window_update(&monitor);

  rt_thread_init(
      &SDL_ptr, "SDL_Thread", sdl_event_handler, RT_NULL,
      &SDL_stack[0], sizeof(SDL_stack), 0, 1000);
  if (rt_thread_startup(&SDL_ptr) == RT_EOK)
  {
    printf("SDL_Thread started\n");
  }
  else
  {
    printf("ERROR:SDL_Thread not started\n");
  }
  TFT_Clear(0, 0, TFT_LESS_PIXEL, TFT_MORE_PIXEL);

  printf("tft simulator init done...\n");
  #endif
}
/******************************************
函数名：Lcd写命令函数
功能：向Lcd指定位置写入应有命令或数据
入口参数：Index 要寻址的寄存器地址
          ConfigTemp 写入的数据或命令值
******************************************/
static void LCD_WR_REG(u16 Index, u16 CongfigTemp)
{
  WriteComm(Index);
  WriteData(CongfigTemp);
}

/**********************************************
函数名：Lcd块选函数
功能：选定Lcd上指定的矩形区域

注意：xStart、yStart、Xend、Yend随着屏幕的旋转而改变，位置是矩形框的四个角

入口参数：xStart x方向的起始点
          ySrart y方向的起始点
          Xend   y方向的终止点
          Yend   y方向的终止点
返回值：无
***********************************************/
void BlockWrite(unsigned int Xstart, unsigned int Xend, unsigned int Ystart,
                unsigned int Yend)
{
}

/**
 * @brief : 颜色填充
 * @param {*}
 * @return {*}
 */
void TFT_Clear2(unsigned int x0, unsigned int y0, unsigned int x1,
                unsigned int y1, uint16_t color)
{

  //原版
  int width = abs(x1 - x0) + 1;
  int height = abs(y1 - y0) + 1;
  int x = x1 >= x0 ? x0 : x1;
  int y = y1 >= y0 ? y0 : y1;
  int all = width * height;

  int i = 0;
  for (i = 0; i < height; i++)
  {
    memset(&monitor.tft_fb[x + (y + i) * MONITOR_HOR_RES], color, width * sizeof(uint16_t));
  }
}
/**
  * @brief  设置LCD的背景颜色,RGB565
  * @param  Color: 指定背景颜色 
  * @retval None
  */
void TFT_SetBackColor(uint16_t Color)
{
  CurrentBackColor = Color;
}
/**
  * @brief  设置LCD的前景(字体)颜色,RGB565
  * @param  Color: 指定前景(字体)颜色 
  * @retval None
  */
void TFT_SetTextColor(uint16_t Color)
{
  CurrentTextColor = Color;
}
/**
 * @brief : 绘制图像
 * @param {uint16_t} x
 * @param {uint16_t} y
 * @param {uint16_t} width
 * @param {uint16_t} height
 * @return {*}
 */
void TFT_DrawBitmap(uint16_t x, uint16_t y, uint16_t width, uint16_t height, uint16_t *pic)
{
}
void TFT_DrawBitmap2(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t *pic, uint8_t direction)
{
}
int get_MeasureX_FromSDL(void)
{
  return touchX;
}
int get_MeasureY_FromSDL(void)
{
  return touchY;
}